package com.fishery.message.controller;


import com.fasteat.common.entity.Result;
import com.fishery.message.service.MsmService;
import com.fishery.message.utils.IpAddressUtil;
import com.fishery.message.utils.RandomUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 白sa能
 * @className
 * @date Created in 10:49 AM 1/14/21
 * @package com.fishery.message.controller
 * @Description
 */
@RestController
@Api(description="短信服务")
@RequestMapping("/message")
public class MsmController {
    @Autowired
    private MsmService msmService;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Value("${aliyun.ttl}")
    private long ttl;

    @Value("${aliyun.ttl2}")
    private long ttl2;

    @Value("${aliyun.times}")
    private long Times;

    /**
     * 发送短信验证码
     * @param phone
     * @param type
     * @return
     */
    @ApiOperation(value = "短信验证码")
    @GetMapping("sendVerify/{type}/{phone}")
    public Result sendVerify(@PathVariable String phone,
                             @PathVariable int type,
                             HttpServletRequest request
                             ) {

        //2.检查是否是恶意请求
        /**
         * redis存入ip+phone，获取value，小于times则允许进行验证码获取，大于times返回错误，
         * 设置验证码过期时间。
         * 用户执行发送验证码接口，无论是否成功，在排除发送次数小于当天发送次数后，发送发送成功的通知；
         * 如果redis中没有验证码存在。则阿里云发送并存进redis
         */
        //获取ip地址,将ip存入redis作为key,验证码作为value,限制每个ip每天可发送短信个数,防止恶意发短信，每次发送验证码都会往redis存ip和手机号的发送次数

        //获取request中的ip地址
        String ipAddress = (IpAddressUtil.getIpAdrress(request));
        //将ipAddress拼接手机号作为key存入redis
        String ipAddressPhone = phone + ipAddress;
        //获取redis中对应的ipAddressPhone的获取次数
        Object ipNum = redisTemplate.opsForValue().get(ipAddressPhone);
        //如果ipAddressPhone在当前周期尚未存入过，则存入1,否则存入ipNum + 1
        if(ipNum == null) {
            redisTemplate.opsForValue().set(ipAddressPhone, "1");
        } else {
            int ipAddrNumInt = Integer.parseInt((String) ipNum);
            redisTemplate.opsForValue().set(ipAddressPhone, String.valueOf(ipAddrNumInt + 1), ttl2, TimeUnit.HOURS);

            // 次数超过限制，返回错误，当前为每分钟只能发1次
            if (ipAddrNumInt > Times) {
//                return new Result(false, StatusCode.ERROR, "请求次数过于频繁，请" + ttl + "分钟后重试", null);
                return Result.error("请求次数过于频繁，请" + ttl2 + "小时后重试");
            }
        }
        //2.从redis获取验证码，如果获取到直接返回
        String code = redisTemplate.opsForValue().get(phone);
        if(!StringUtils.isEmpty(code)) {
            return Result.error().message("请求过于频繁，请稍后再试");
        }
        //3.如果redis获取不到，进行阿里云发送
        //生成随机值，传递阿里云进行发送
        code = RandomUtil.getFourBitRandom();
        Map<String,Object> param = new HashMap<>();
        param.put("code",code);
        //调用service发送短信的方法
        boolean isSend = msmService.sendVerify(param, phone, type);
        if(isSend) {
            //发送成功，把发送成功验证码放到redis里面
            //设置有效时间
            redisTemplate.opsForValue().set(phone, code, ttl, TimeUnit.MINUTES);
            return Result.success().message("短信发送成功");
//            return Result.success("短信发送成功");
        } else {
            return Result.error().message("短信发送失败");
//            return Result.error("短信发送失败，请重新尝试");
        }
    }

//    /**
//     * 发送短信通知
//     * @param phone
//     * @param time
//     * @param param
//     * @return
//     */
//    @ApiOperation(value = "通知短信")
//    @GetMapping("sendRemind/{time}/{param}/{phone}")
//    public Result sendRemind(@PathVariable String phone,
//                             @PathVariable String time,
//                             @PathVariable String param) {
//        //调用service发送短信的方法
//        boolean isSend = msmService.sendRemind(time, param, phone);
//        if(isSend) {
//            return Result.success();
//        } else {
//            return Result.error().message("短信发送失败");
//        }
//    }
}
